package org.chen.wx.utils;

import lombok.extern.slf4j.Slf4j;
import org.chen.api.core.OkHttpClientManager;
import org.chen.api.request.StringRequest;
import org.chen.api.utils.JsonUtil;
import org.chen.wx.dto.AccessToken;
import org.chen.wx.dto.BaseAccessToken;
import org.chen.wx.dto.WxUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * Author:Mr.Chen
 * Date:2018/8/3
 */
@Slf4j
@Component
public class WxUserInfoUtils {

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.basetoken}")
    private String basetoken;

    @Value("${wx.accesstoken}")
    private String accesstoken;

    @Value("${wx.secret}")
    private String secret;

    @Value("${wx.userinfo}")
    private String userinfo;

    @Value("${wx.redisexpires}")
    private Long redisexpires;

    @Resource()
    private OkHttpClientManager clientManager;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取基础token
     */
    public BaseAccessToken getBaseAccessToken() {
        String baseAccessStr = (String) redisTemplate.opsForValue().get("base_token");
        BaseAccessToken baseAccessToken = JsonUtil.fromJson(baseAccessStr, BaseAccessToken.class);
        if (baseAccessToken == null) {
            StringRequest request = new StringRequest(basetoken);
            request.add("grant_type", "client_credential").add("appid", appid).add("secret", secret);
            baseAccessToken = JsonUtil.fromJson(clientManager.send(request).getRawBody(), BaseAccessToken.class);
            redisTemplate.opsForValue().set("base_token", JsonUtil.toJson(baseAccessToken));
            redisTemplate.expire("base_token", redisexpires, TimeUnit.SECONDS);
            log.info("==============获取基础token==============\n" + JsonUtil.toJson(baseAccessToken));
        }
        return baseAccessToken;
    }

    /**
     * 通过code换取网页授权access_token(包含用户OpenId)
     *
     * @param code 微信服务器返回的Code
     */
    public AccessToken getAccessToken(String code) {
        StringRequest request = new StringRequest(accesstoken);
        request.add("appid", appid).add("secret", secret).add("code", code).add("grant_type", "authorization_code");
        AccessToken accessToken = JsonUtil.fromJson(clientManager.send(request).getRawBody(), AccessToken.class);
        log.info("==============获取网页授权access_token==============\n");
        return accessToken;
    }

    /**
     * 通过获取用户基本信息
     *
     * @param openid 普通用户的标识，对当前公众号唯一 openid
     */
    public WxUserInfo getUserInfo(String openid) {
        String baseAccessStr = (String) redisTemplate.opsForValue().get("base_token");
        BaseAccessToken baseAccessToken = JsonUtil.fromJson(baseAccessStr, BaseAccessToken.class);
        if (baseAccessToken == null) {
            baseAccessToken = getBaseAccessToken();
            redisTemplate.opsForValue().set("base_token", JsonUtil.toJson(baseAccessToken));
            redisTemplate.expire("base_token", redisexpires, TimeUnit.SECONDS);
        }
        StringRequest request = new StringRequest(userinfo);
        request.add("access_token", baseAccessToken.getAccess_token()).add("openid", openid).add("lang", "zh_CN");
        WxUserInfo wxUserInfo = JsonUtil.fromJson(clientManager.send(request).getRawBody(), WxUserInfo.class);
        log.info("==============获取用户基本信息==============\n" + JsonUtil.toJson(wxUserInfo));
        return wxUserInfo;
    }

}
